﻿using System;
using System.IO;
using Rabbit.Model;
using Rabbit.OAuthCore;
using Rabbit.Utils;
namespace Rabbit.BusinessLogicLayer
{
    public class RequestHelper
    {
        private static OAuthHelper oAuthHelper;
        public static string AccessToken{get;private set;}
        public static string AccessTokenSecret{get;private set;}
        private static string APIBaseUrl = string.Empty;

        /// <summary>
        /// set the oAuth related Url
        /// </summary>
        /// <param name="requestTokenUrl"></param>
        /// <param name="authorizationTokenUrl"></param>
        /// <param name="accessTokenUrl"></param>
        /// <param name="consumerKey"></param>
        /// <param name="consumerSecret"></param>
        public static void SetOAuthBaseUrl(string requestTokenUrl, string authorizationTokenUrl, string accessTokenUrl, string consumerKey, string consumerSecret, string apiBaseUrl)
        {
            oAuthHelper = new OAuthHelper(requestTokenUrl, authorizationTokenUrl, accessTokenUrl, consumerKey, consumerSecret);
            APIBaseUrl = apiBaseUrl;
        }

        public static void SetAccessToken(UserSettings token)
        {
            AccessToken = token.TokenID;
            AccessTokenSecret = token.TokenSecret;
            oAuthHelper.AccessToken = token.TokenID;
            oAuthHelper.AccessTokenSecret = token.TokenSecret;
        }

        private RequestHelper()
        {
        }

        public static void SetAPIBaseUrl(string baseUrl)
        {
            APIBaseUrl = baseUrl;
        }

        public static string GetAuthorizationUrl()
        {
            return oAuthHelper.GetAuthorizationUrl(HttpMethod.GET);
        }

        public static void GenerateAccessToken(string verifyCode)
        {
            oAuthHelper.GenerateAccessToken(verifyCode);
            AccessToken = oAuthHelper.AccessToken;
            AccessTokenSecret = oAuthHelper.AccessTokenSecret;
        }

        public static string SendRequest(string url, string parameter, string method="Get")
        {
            if (!url.StartsWith("http"))
            {
                url = new Uri(new Uri(APIBaseUrl),url).ToString();
            }

            try
            {
                string result = oAuthHelper.SendRequest(url, parameter, (HttpMethod)Enum.Parse(typeof(HttpMethod), method, true));
                if (string.IsNullOrEmpty(result))
                {
                    throw new NullStringReceviedFromServerException("got empty string from the server");
                }
                return result;
            }
            catch (System.Net.WebException ex)
            {
                //TODO this should be refined later, we shouldn't throw SameStatusHasBeenPostedException all the time
                if (ex.Status == System.Net.WebExceptionStatus.ProtocolError)
                {
                    throw new SameStatusHasBeenPostedException();
                }
                else
                {
                    throw;
                }
            }
            catch (Exception ex)
            {
                LogHelper.LogError(ex);

                string result = oAuthHelper.SendRequest(new Uri(new Uri(APIBaseUrl), "account/rate_limit_status.json").ToString(), "");
                RatesLeft leftRates = Utils.JsonHelper.Deserialize<RatesLeft>(result);
                if (leftRates.RemainingHits == 0)
                {
                    leftRates.ResetTime = DateTimeHelper.GetDateTimeFromString(leftRates.ResetTime).ToShortTimeString();
                    throw new MaxRatesExceededException()
                    {
                        RatesInformation = leftRates
                    };
                }
                else
                {
                    throw;
                }
            }
        }

        public static string SendRequestWithPicture(string url,string pictureRemark , string picturePath)
        {
            return SendRequestWithPicture(url, pictureRemark, File.OpenRead(picturePath));
        }
         
        public static string SendRequestWithPicture(string url, string pictureRemark, Stream pictureStream)
        {
            if (!url.StartsWith("http"))
            {
                url = new Uri(new Uri(APIBaseUrl), url).ToString();
            }
            return oAuthHelper.SendPostWithPicture(url, pictureRemark,pictureStream);
        }
    }
}
